using System;
using System.Collections.Generic;
using System.Text;

namespace Crainiate.Data.Persistence.Providers
{
    public abstract class Command
    {
        public abstract Context Context {get; set;}

        public abstract void Select(IPersistable graph); //Load one record
        public abstract void Insert(IPersistable graph);
        public abstract void Execute(IQuery query); //Load many records
        public abstract void Update(IPersistable graph);
        public abstract void Delete(IPersistable graph);
        public abstract bool Exists(IPersistable graph); //Exists one record
        public abstract void Promote(IPersistable graph);
        public abstract void Demote(IPersistable graph);
        public abstract void Reset();

        protected static bool IsComplexQuery(IQuery query)
        {
            return (GetQueryFillCount(query) > 1);
        }

        protected static IQuery FindQuery(IQuery query)
        {
            IQuery result = GetSingleFilledQuery(query);
            if (result == null) return query;
            return result;
        }

        //Counts the number of filled queries
        private static int GetQueryFillCount(IQuery query)
        {
            int i = 0;

            if (query.Fill) i = 1;
            if (query.SubQueries == null || query.SubQueries.Count == 0) return i;

            foreach (IQuery subquery in query.SubQueries)
            {
                i += GetQueryFillCount(subquery);
            }

            return i;
        }

        private static IQuery GetSingleFilledQuery(IQuery query)
        {
            if (query.Fill) return query;
            if (query.SubQueries == null) return null;

            foreach (IQuery subquery in query.SubQueries)
            {
                IQuery result = GetSingleFilledQuery(subquery);

                if (result != null) return result;
            }
            return null;
        }
    }
}